<template>
    <view v-if="isCalendar" class="calendar_box">
        <view v-show="!isTime" class="btn_calendar_box">
            <view class="btn_box">
                <view class="cancel" @click="cancel">取消</view>
                <view class="tab_bar_box">
                    <view class="tab_bar_item" :class="[calendarType === 'solar' ? 'activation_tab_bar' : '']"
                        @click="tabBar('solar')">公历</view>
                    <view class="tab_bar_item" :class="[calendarType === 'lunar' ? 'activation_tab_bar' : '']"
                        @click="tabBar('lunar')">农历</view>
                </view>
                <view class="confirm" @click="confirm">确认</view>
            </view>

            <picker-view :indicator-style="indicatorStyle" :value="defaultValue" @change="bindChange"
                style="width:750upx; height: 400upx;">
                <picker-view-column>
                    <view class="picker_item" v-for="item in years" :key="item.id">{{ calendarType === 'solar' ?
                        item.lYear
                        : item.l_gz_Year }}
                    </view>
                </picker-view-column>

                <picker-view-column>
                    <view class="picker_item" v-for="item in months" :key="item.id">{{ calendarType === 'solar' ?
                        item.cMonth
                        : item.IMonthCn }}</view>
                </picker-view-column>

                <picker-view-column>
                    <view class="picker_item" v-for="item in days" :key="item.id">{{ calendarType === 'solar' ?
                        item.cDay
                        : item.IDayCn }}</view>
                </picker-view-column>

                <picker-view-column>
                    <view class="picker_item" v-for="item in hours" :key="item.id">{{ item.title }}</view>
                </picker-view-column>
                <picker-view-column>
                    <view class="picker_item" v-for="item in mins" :key="item.id">{{ item.title }}</view>
                </picker-view-column>
            </picker-view>
        </view>

        <view v-show="isTime" class="confirm_time_box">
            <view class="confirm_time_title">确认时间</view>
            <view class="input_time">请确认输入的时间是否正确</view>
            <view>
                <view class="value_box">
                    公(阳)历：{{ year.lYear }}{{ month.cMonth }}{{ day.cDay }}{{ hour.title }}{{ min.title }}
                </view>
                <view class="value_box">
                    农(阴)历：{{ year.gzYear }}{{ month.IMonthCn }}{{ day.IDayCn }}{{ hour.title }}{{ min.title }}
                </view>
            </view>

            <view class="back_correct_btn_box">
                <view class="back_edit" @click="backEdit">返回修改</view>
                <view class="correct" @click="alreadyCorrect">确认正确</view>
            </view>
        </view>
    </view>
</template>

<script>
// solar2lunar 阳转阴
// lunar2solar 阴转阳
const jsCalendarConverter = require('js-calendar-converter');
const calendar = jsCalendarConverter.default;

export default {
    name: 'selectCalendar',
    data() {
        return {
            // lunar 阴历
            // solar 阳历
            calendarType: 'solar',
            defaultValue: [0, 5, 16, 17, 18],
            years: [],
            year: {},
            months: [],
            month: {},
            days: [],
            day: {},
            hours: [],
            hour: {},
            mins: [],
            min: {},
            indicatorStyle: undefined,
            dayIndex: 0,
            isTime: false,
            isCalendar: false,
            birthdayVal: ''
        }
    },
    methods: {
        // 确认正确
        alreadyCorrect() {
            let year = this.year,
                month = this.month,
                day = this.day,
                hour = this.hour,
                min = this.min,
                birthdayVal = '',
                calendarType = this.calendarType;

            if (calendarType === 'solar') {
                birthdayVal += year.lYear;
                birthdayVal += month.cMonth;
                birthdayVal += day.cDay;
            } else {
                birthdayVal += year.gzYear;
                birthdayVal += month.IMonthCn;
                birthdayVal += day.IDayCn;
            }

            birthdayVal += hour.title;
            birthdayVal += min.title;

            this.birthdayVal = birthdayVal;
            this.isCalendar = false;
            this.isTime = false;

            this.$emit('backData', { year, month, day, hour, min, calendarType, birthdayVal });
        },
        /**
         * 设置面板默认值/年月日时分
         * @author mj <1283077926@qq.com>
         * @license Apache-2.0
         * @param {Date} dateNow 
         * @param {number} startYear 
         * @param {number} endYear 
         * @return {undefined} undefined
         */
        getTime(dateNow, startYear, endYear) {
            let years = [],
                year = dateNow.getFullYear(),
                months = [],
                month = dateNow.getMonth() + 1,
                days = [],
                day = dateNow.getDate(),
                hours = [],
                hour = dateNow.getHours() + 1,
                mins = [],
                min = dateNow.getMinutes(),
                indexOf = (arr, IO) => arr.indexOf(IO),
                defaultValue = [];

            for (let i = startYear; i <= endYear; i++) years.push(i);
            for (let i = 0; i < 12; i++) months.push(i + 1);
            for (let i = 0; i < 31; i++) days.push(i + 1);
            for (let i = 0; i < 24; i++) hours.push(i);
            for (let i = 0; i < 60; i++) mins.push(i);

            defaultValue = [
                indexOf(years, year),
                indexOf(months, month),
                indexOf(days, day),
                indexOf(hours, hour),
                indexOf(mins, min)
            ];

            this.defaultValue = defaultValue;
        },
        /**
         * 打开日期选择器
         * @author mj <1283077926@qq.com>
         * @license Apache-2.0
         * @param {Date} dateNow 
         * @param {number} startYear 
         * @param {number} endYear 
         * @return {undefined} undefined
         */
        openCalendar(dateNow = new Date(), startYear, endYear) {
            startYear = startYear ? startYear : 1900;
            endYear = endYear ? endYear : dateNow.getFullYear();

            startYear = startYear < 1900 ? 1900 : startYear;
            endYear = endYear > 2100 ? 2100 : endYear;

            this.getTime(dateNow, startYear, endYear);

            this.indicatorStyle = `height: ${Math.round(uni.getSystemInfoSync().screenWidth / (750 / 80))}px;`;
            this.init(startYear, endYear);
            this.isCalendar = true;
        },
        // 取消
        cancel() {
            this.isCalendar = false;
            this.birthdayVal = '';
            this.calendarType = 'solar';
            this.$emit('backData', { year: {}, month: {}, day: {}, hour: {}, min: {}, calendarType: 'solar', birthdayVal: '' });
        },
        // 返回修改
        backEdit() {
            this.isTime = false;
        },
        tabBarConfirm() {
            let year = this.year,
                month = this.month,
                day = this.day,
                { lYear, gzYear, IMonthCn, cMonth, IDayCn, cDay } = calendar.solar2lunar(year.num, month.num, day.num);

            this.year = {
                id: year.id,
                lYear: lYear + '年',
                gzYear: gzYear + '年',
                l_gz_Year: lYear + gzYear + '年',
                num: lYear
            };
            this.month = {
                id: month.id,
                IMonthCn,
                cMonth: cMonth + '月',
                num: cMonth
            };
            this.day = {
                id: day.id,
                IDayCn: IDayCn,
                cDay: cDay + '日',
                num: cDay
            };
        },
        // 确认
        confirm() {
            this.tabBarConfirm();
            this.isTime = true;
        },
        // 阴阳历转换
        tabBar(type) {
            this.tabBarConfirm();
            this.calendarType = type;
        },
        // 滑动触发
        bindChange(event) {
            let valArr = event.detail.value;

            this.year = this.years[valArr[0]];

            if (this.calendarType === 'lunar') {
                let dayI = valArr[2],
                    isTB = dayI - this.dayIndex,
                    monI = valArr[1];

                if (isTB === 1 && this.days[dayI].IDayCn === '初一') valArr[1] = monI + 1;

                if (isTB === -1 && (['廿八', '廿九', '三十'].includes(this.days[dayI].IDayCn))) valArr[1] = monI - 1;

                this.defaultValue = valArr;
                this.dayIndex = dayI;
            }

            this.hour = this.hours[valArr[3]];
            this.min = this.mins[valArr[4]];

            // 根据年份生成月份数据
            this.getMonth(this.year.num, valArr[1], valArr[2]);
        },
        // 月份数据
        getMonth(year, i, j) {
            let months = [];

            for (let n = 0; n < 12; n++) {
                let { IMonthCn, cMonth } = calendar.solar2lunar(year, n + 1, 28);
                months.push({
                    id: `id${n + 1}`,
                    IMonthCn,
                    cMonth: cMonth + '月',
                    num: cMonth
                });
            }

            this.months = months;
            this.month = this.months[i];

            // 根据年份和月份生成日期数据
            this.getDay(this.year.num, this.month.num, j);
        },
        // 日期
        getDay(year, month, i) {
            let isZero = year % 4 === 0,
                len = [1, 3, 5, 7, 8, 10, 12].includes(month) ? 31 : [4, 6, 9, 11].includes(month) ? 30 : isZero ? 29 : 28,
                days = [],
                daysLen = 0;

            for (let i = 0; i < len; i++) {
                let { IDayCn, cDay } = calendar.solar2lunar(year, month, i + 1);

                days.push({
                    id: `id${i + 1}`,
                    IDayCn: IDayCn,
                    cDay: cDay + '日',
                    num: cDay
                });
            }

            this.days = days;
            days = this.days;
            daysLen = days.length - 1;
            i = i > daysLen ? daysLen : i;
            this.day = this.days[i];
        },
        // 初始化
        init(startYear, endYear) {
            let years = [],
                hoursArr = ["未知时辰", "子", "丑", "丑", "寅", "寅", "卯", "卯", "辰", "辰", "巳", "巳", "午", "午", "未", "未", "申", "申", "酉", "酉", "戌", "戌", "亥", "亥", "子"],
                hours = [],
                mins = [],
                valArr = this.defaultValue;

            // 生成年份
            for (let i = startYear; i <= endYear; i++) {
                let { lYear, gzYear } = calendar.solar2lunar(i, 5, 1);

                years.push({
                    id: `id${i}`,
                    lYear: lYear + '年',
                    gzYear: gzYear + '年',
                    l_gz_Year: lYear + gzYear + '年',
                    num: lYear
                });
            }

            this.years = years;
            this.year = this.years[valArr[0]];

            // 根据年份生成月份数据
            this.getMonth(this.year.num, valArr[1], valArr[2]);

            // 时辰数据
            for (let i = 0; i < 25; i++) hours.push({
                id: `id_${i + 1}`,
                title: i !== 0 ? (i - 1) + hoursArr[i] : hoursArr[i],
                value: i - 1,
                num: i - 1
            });

            // 分钟数据
            for (let i = 0; i < 60; i++) mins.push({
                id: `id_${i + 1}`,
                title: i + '分',
                value: i,
                num: i
            });

            this.hours = hours;
            this.mins = mins;
            this.hour = this.hours[valArr[3]];
            this.min = this.mins[valArr[4]];
        }
    }
}
</script>

<style>
.calendar_box {
    position: fixed;
    left: 0;
    top: 0;
    width: 100vw;
    height: calc(100vh - 58px);
    display: flex;
    flex-direction: column-reverse;
    background-color: rgba(200, 200, 200, .8);
    z-index: 6;
}

.btn_calendar_box {
    background-color: #ffffff;
    padding-top: 12upx;
    padding-bottom: 12upx;
    z-index: 7;
}

.btn_box {
    padding: 8upx 16upx;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.tab_bar_box {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border: 1upx solid rgb(201, 23, 35);
    border-radius: 10upx;
}

.tab_bar_item {
    height: 40upx;
    line-height: 40upx;
    padding: 10upx 30upx;
    color: rgb(201, 23, 35);
    cursor: pointer;
}

.activation_tab_bar {
    background: rgb(201, 23, 35);
    color: #FFFFFF;
}

.cancel {
    color: rgb(153, 153, 153);
    cursor: pointer;
    font-size: 32upx;
}

.confirm {
    color: rgb(201, 23, 35);
    cursor: pointer;
    font-size: 32upx;
}

.picker_item {
    height: 80upx;
    line-height: 80upx;
    text-align: center;
    font-size: 28upx;
}

/* ------------------------------- */
.confirm_time_box {
    background-color: #ffffff;
    padding-top: 12upx;
    padding-bottom: 12upx;
    z-index: 7;
}

.confirm_time_title {
    text-align: center;
    color: rgb(201, 23, 35);
    font-size: 32upx;
    border-bottom: 1upx solid #E8E8E8;
    height: 88upx;
    line-height: 88upx;
}

.input_time {
    text-align: center;
    font-size: 34upx;
    color: #000000;
    height: 48upx;
    line-height: 48upx;
    margin-top: 48upx;
    padding-bottom: 20upx;
}

.value_box {
    text-align: center;
    font-size: 34upx;
    color: rgb(163, 30, 26);
    height: 34upx;
    line-height: 34upx;
    padding: 10upx 0px;
}

.back_correct_btn_box {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 40upx 0;
    color: #ffffff;
}

.back_edit {
    padding: 20upx 40upx;
    border-radius: 10upx;
    background-color: #DDDDDD;
}

.correct {
    padding: 20upx 40upx;
    margin-left: 40upx;
    border-radius: 10upx;
    background-color: rgb(163, 30, 26);
}
</style>